package com.wdciti.sccp.iot.gateway.endpoint.pib;

import com.wdciti.sccp.iot.gateway.domain.Channel;
import com.wdciti.sccp.iot.gateway.domain.TagPosition;
import com.wdciti.sccp.iot.gateway.utils.RedisUtil;
import com.wdciti.sccp.iot.springvertx.annotation.VerticleBean;
import io.vertx.core.AbstractVerticle;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.datagram.DatagramPacket;
import io.vertx.core.datagram.DatagramSocket;
import io.vertx.core.datagram.DatagramSocketOptions;
import io.vertx.core.json.JsonArray;
import io.vertx.core.json.JsonObject;
import io.vertx.core.net.SocketAddress;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;

/**
 * 对梦芯接口，httpclient请求后，按平台格式发MQTT给平台。
 *
 * @author JINWEN
 */
@Slf4j
@VerticleBean(isWorker = false)
public class PibAdapterVerticle extends AbstractVerticle {

    @Value("${pib.udp.ip}")
    private String pibIp;

    @Value("${pib.udp.port}")
    private Integer pibPort;

    @Autowired
    private RedisUtil redisUtil;

    private static final String SEND_DATA_BUS_ADDR = "addr:location/now/pib";

    @Override
    public void start() {
        try {
            // 设置接收缓冲区大小为 10 MB
            DatagramSocketOptions options = new DatagramSocketOptions()
                    .setReceiveBufferSize(20 * 1024 * 1024);

            DatagramSocket socket = vertx.createDatagramSocket(options);
            socket
                    .handler(this::handlePacket)
                    .listen(pibPort, pibIp)
                    .onComplete(asyncResult -> {
                        if (asyncResult.succeeded()) {
                            log.info("UDP Socket started successfully on {}:{}", pibIp, pibPort);
                        } else {
                            log.error("Failed to start UDP Socket: {}", asyncResult.cause().getMessage());
                        }
                    });
        } catch (Exception e) {
            log.error("Error starting UDP Socket: {}", e.getMessage(), e);
        }
    }

    private void handlePacket(DatagramPacket packet) {
        SocketAddress address = packet.sender();
        log.info("Received packet from: {}:{}", address.host(), address.port());
        Buffer buffer = packet.data();
        log.info("Received data size: {} bytes", buffer.length());

        try {
            JsonObject jsonObject = buffer.toJsonObject();
            if (validateData(jsonObject)) {
                sendData(jsonObject);
            } else {
                log.warn("Invalid data received: {}", jsonObject);
            }
        } catch (Exception e) {
            log.error("Error parsing JSON data: {}", e.getMessage(), e);
        }
    }

    private boolean validateData(JsonObject jsonObject) {
        return jsonObject.containsKey("timestamp") &&
                jsonObject.containsKey("tagId") &&
                jsonObject.containsKey("lng") &&
                jsonObject.containsKey("lat") &&
                jsonObject.containsKey("alt");
    }

    private void sendData(JsonObject jsonObject) {
        TagPosition position = new TagPosition();
        position.setTimestamp(jsonObject.getLong("timestamp"));
        position.setAlive(true);
        position.setLongitude(jsonObject.getDouble("lng")); // 经度
        position.setLatitude(jsonObject.getDouble("lat"));  // 纬度
        position.setHigh(jsonObject.getDouble("alt")); // 高度
        String tagId = jsonObject.getString("tagId", "");
        if (tagId.isEmpty()) {
            return;
        }
        position.setTagId(tagId);   // 标签ID
        position.setCardId(tagId); // 卡片ID也是tagId
        position.setChannel(Channel.pib.name());

        // 解析电量数据存redis
        JsonArray array = jsonObject.getJsonArray("extras", JsonArray.of());
        JsonObject obj = JsonObject.of("cardId", tagId);
        for (int i = 0; i < array.size(); i++) {
            JsonObject item = array.getJsonObject(i);
            String key = item.getString("key");
            if ("voltage".equals(key)) {
                obj.put("voltage", item.getString("val"));
            }
            if ("power".equals(key)) {
                obj.put("power", item.getString("val"));
            }
        }
        redisUtil.setCacheMapValue("pibPower", tagId, obj.toString());

        JsonObject object = JsonObject.mapFrom(position);
        log.info("pib Position-+-：{}", object);
        vertx.eventBus().send(SEND_DATA_BUS_ADDR, object);
    }
}
